/*                 登录注册界面             */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <sys/mman.h>
#include <linux/input.h>

#include "show_bmp.h"
#include "LCD.h"
#include "font.h"
#include "fonts.h"

#include "login_system.h"
#include "login.h"

int temp_pixels[TEMP_HEIGHT][TEMP_WIDTH];
int x, y; // 坐标初始值是-1
int vary = 0;

struct input_event touch_event; // 触摸屏数据结构体
char *login_system()
{
    int lcd_fd = open("/dev/fb0", O_RDWR);
    if (lcd_fd <= 0)
    {
        perror("Failed to open frame buffer device");
        return NULL;
    }
    int(*lcd_mmap)[WIDTH] = (int(*)[WIDTH])mmap(NULL, WIDTH * HEIGHT * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd, 0);

    lcd_clear();                                 // 清屏
    show_bmp("./res/login_bmp/login.bmp", 0, 0); // 登录界面背景
    show_bmp("./res/exit.bmp", 0, 0);
    login_interface();

    // 打开触摸屏设备文件
    int touch_fd = open("/dev/input/event0", O_RDWR);
    if (touch_fd <= 0)
    {
        perror("打开触摸设备失败");
        return NULL;
    }

    char *account = NULL;  // 获取账号输入
    char *password = NULL; // 获取密码输入

    int gg = 0;
register_ins:
    while (1)
    {

        // 读取触摸屏设备文件数据
        int read_ret = read(touch_fd, &touch_event, sizeof(struct input_event));
        if (read_ret < 0)
        {
            perror("读取触摸事件失败");
            return NULL;
        }
        // 获取每次触摸坐标
        if (touch_event.type == EV_ABS)
        {
            switch (touch_event.code)
            {
            case ABS_X:
                x = touch_event.value;
                break;
            case ABS_Y:
                y = touch_event.value;
                break;
            }
            // printf("%d %d\n",x,y);
        }
        // 根据触摸坐标选择对应功能
        if (touch_event.type == EV_KEY)
        {
            if (touch_event.code == BTN_TOUCH && touch_event.value == 0)
            {
                if (y <= 40 && x <= 40) // 退出程序
                {
                    lcd_clear();
                    exit(0);
                }

                if (x > 310 && y > 160 && x < 530 && y < 195)
                {
                    save_area(240, 200, lcd_mmap);
                    account = account_insert(touch_fd, lcd_mmap);
                }
                if (x > 310 && y > 200 && x < 530 && y < 235)
                {
                    save_area(240, 240, lcd_mmap);
                    password = password_insert(touch_fd, lcd_mmap);
                }

                else if (gg == 100)
                {
                    if (x > 300 && y > 250 && x < 480 && y < 310)
                    {

                        if (account == NULL || password == NULL || strlen(password) == 0)
                        {
                            printf("账号或密码不能为空\n");
                            save_area(270, 150, lcd_mmap);
                            show_bmp("./res/login_bmp/login_failed3.bmp", 270, 150);
                            sleep(1);
                            restore_area(270, 150, lcd_mmap);
                            goto register_ins;
                        }

                        switch (login_function(1, account, password))
                        {
                        case 3: // 账号已存在
                            save_area(270, 150, lcd_mmap);
                            show_bmp("./res/login_bmp/login_failed2.bmp", 270, 150);
                            sleep(1);
                            restore_area(270, 150, lcd_mmap);
                            break;
                        case 2: // 注册成功
                            save_area(270, 150, lcd_mmap);
                            show_bmp("./res/login_bmp/login_successful2.bmp", 270, 150);
                            sleep(1);
                            restore_area(270, 150, lcd_mmap);
                            break;
                        default:
                            break;
                        }
                        printf("%s %s\n", account, password);
                        printf("返回登录\n");
                        account = NULL;
                        password = NULL;
                        login_interface();

                        gg = 0;
                    }
                    goto register_ins;
                }
                if (x > 320 && y > 250 && x < 380 + gg && y < 310)
                {
                    printf("注册\n");
                    register_lcd();
                    // 清空账号密码
                    account = NULL;
                    password = NULL;
                    gg += 100;
                }

                if (x > 430 && y > 250 && x < 490 && y < 310)
                {
                    printf("登录\n");

                    if (account == NULL || password == NULL || login_function(2, account, password) != 1)
                    {
                        printf("登录失败!\n");
                        save_area(270, 150, lcd_mmap);
                        show_bmp("./res/login_bmp/login_failed.bmp", 270, 150);
                        sleep(1);
                        restore_area(270, 150, lcd_mmap);
                        goto register_ins;
                    }

                    goto exit;
                }
            }
        }
    }
exit:
    munmap(lcd_mmap, WIDTH * HEIGHT * 4); // 解除映射
    close(lcd_fd);                        // 关闭文件

    return account;
}

// 登录界面显示
void login_interface()
{

    font_lcd(); // 登录界面字体显示

    show_bmp("./res/login_bmp/register.bmp", 310, 250);

    show_bmp("./res/login_bmp/login2.bmp", 440, 250);
}

// 输入账号
char *account_insert(int touch_fd, int (*lcd_mmap)[WIDTH])
{
    show_bmp("./res/login_bmp/keypad.bmp", 240, 200); // 显示数字键盘图片
    vary = 0;
    char *str = keypad(touch_fd, lcd_mmap);
    return str;
}
// 输入密码
char *password_insert(int touch_fd, int (*lcd_mmap)[WIDTH])
{
    show_bmp("./res/login_bmp/keypad.bmp", 240, 240); // 显示数字键盘图片
    vary = 40;
    char *str = keypad(touch_fd, lcd_mmap);
    return str;
}

// 数字键盘点击事件处理
char *keypad(int touch_fd, int (*lcd_mmap)[WIDTH])
{
    char *buf = malloc(11); // 分配足够的内存，包括终止符
    if (buf == NULL)
    {
        perror("Memory allocation failed");
        exit(EXIT_FAILURE);
    }

    memset(buf, 0, 11);
    if (vary != 0)
    {
        password_lcd(buf);
    }
    else
    {
        account_lcd(buf);
    }
    int index = 0;
    while (1)
    {
        // 读取触摸屏设备文件数据
        int read_ret = read(touch_fd, &touch_event, sizeof(struct input_event));
        if (read_ret < 0)
        {
            perror("读取触摸事件失败");
            break;
        }

        // 获取每次触摸坐标
        if (touch_event.type == EV_ABS)
        {
            switch (touch_event.code)
            {
            case ABS_X:
                x = touch_event.value;
                break;
            case ABS_Y:
                y = touch_event.value;
                break;
            }
        }
        if (index > 9)
        {
            printf("最多10位数\n");
            goto exit_ins;
        }

        // 根据触摸坐标选择对应功能
        if (touch_event.type == EV_KEY)
        {
            // 按下
            if (touch_event.code == BTN_TOUCH && touch_event.value == 1)
            {
                // 数字键盘
                if (x > 248 && y > 205 + vary && x < 344 && y < 257 + vary)
                {
                    buf[index] = '1';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                else if (x > 354 && y > 205 + vary && x < 450 && y < 257 + vary)
                {
                    buf[index] = '2';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                else if (x > 460 && y > 205 + vary && x < 556 && y < 257 + vary)
                {
                    buf[index] = '3';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                if (x > 248 && y > 265 + vary && x < 344 && y < 317 + vary)
                {
                    buf[index] = '4';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                else if (x > 354 && y > 265 + vary && x < 450 && y < 317 + vary)
                {
                    buf[index] = '5';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                else if (x > 460 && y > 265 + vary && x < 556 && y < 317 + vary)
                {
                    buf[index] = '6';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                if (x > 248 && y > 325 + vary && x < 344 && y < 377 + vary)
                {
                    buf[index] = '7';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {

                        account_lcd(buf);
                    }
                    index++;
                }
                else if (x > 354 && y > 325 + vary && x < 450 && y < 377 + vary)
                {
                    buf[index] = '8';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                else if (x > 460 && y > 325 + vary && x < 556 && y < 377 + vary)
                {
                    buf[index] = '9';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }

                else if (x > 248 && y > 384 + vary && x < 344 && y < 436 + vary)
                {
                exit_ins:
                    printf("break\n");
                    if (vary != 0)
                    {
                        restore_area(240, 240, lcd_mmap);
                    }
                    else
                        restore_area(240, 200, lcd_mmap);

                    break;
                }
                else if (x > 354 && y > 384 + vary && x < 450 && y < 436 + vary)
                {
                    buf[index] = '0';
                    if (vary != 0)
                    {
                        password_lcd(buf);
                    }
                    else
                    {
                        account_lcd(buf);
                    }
                    index++;
                }
                else if (x > 460 && y > 384 + vary && x < 556 && y < 436 + vary)
                {
                    if (index > 0)
                    {
                        buf[index - 1] = '\0';
                        if (vary != 0)
                        {
                            password_lcd(buf);
                        }
                        else
                            account_lcd(buf);
                        index--;
                        printf("撤回\n");
                    }
                }
            }
        }
    }
    vary = 0;
    if (index > 0)
    {
        buf[index] = '\0'; // 确保最后一个字符后面有空字符
    }

    return buf;
}

// 保存显示图片前区块像素
void save_area(int x, int y, int (*lcd_mmap)[WIDTH])
{
    for (int i = 0; i < TEMP_HEIGHT; ++i)
    {
        for (int j = 0; j < TEMP_WIDTH; ++j)
        {
            temp_pixels[i][j] = lcd_mmap[y + i][x + j];
        }
    }
}

// 恢复保存的像素数据
void restore_area(int x, int y, int (*lcd_mmap)[WIDTH])
{
    for (int i = 0; i < TEMP_HEIGHT; ++i)
    {
        for (int j = 0; j < TEMP_WIDTH; ++j)
        {
            lcd_mmap[y + i][x + j] = temp_pixels[i][j];
        }
    }
}
